#![allow(unused_imports)]
#![allow(unused_variables)]

use std::error::Error ;
use std::marker::PhantomData;
use reqwest ;
use serde_json::Value ;
use async_trait::async_trait ;

pub mod types {
    use std::collections::HashMap ;
    #[derive(Debug)]
    pub struct CreateTopicReq  {
        pub topic: String,
        pub partitions: Option<u64>,
        pub config: HashMap<String, String>,
    }
    #[derive(Debug)]
    pub struct DeleteTopicReq {
        pub topic: String
    }
    #[derive(Debug)]
    pub struct ListTopicReq {
    }

    #[derive(Debug)]
    pub struct CreateConsumeGroupReq {
        pub group: String
    }
    #[derive(Debug)]
    pub struct DeleteConsumeGroupReq {
        pub group: String
    }
    #[derive(Debug)]
    pub struct ListConsumeGroupReq {
    }
}

use types::* ;

#[async_trait]
pub trait KafkaClient : Sync {
    async fn create_topic(&self, req: CreateTopicReq) -> anyhow::Result<Value>;
    async fn delete_topic(&self, req: DeleteTopicReq) -> anyhow::Result<Value>;
    async fn list_topic(&self, req: ListTopicReq) -> anyhow::Result<Value> ;

    async fn create_consume_group(&self, req: CreateConsumeGroupReq) -> anyhow::Result<Value>;
    async fn delete_consume_group(&self, req: DeleteConsumeGroupReq) -> anyhow::Result<Value>;
    async fn list_consume_group(&self, req: ListConsumeGroupReq) -> anyhow::Result<Value>;
}


pub struct KafkaPlugin {
    pub new_client: fn(bootstrap_server: &str) -> Option<Box<dyn KafkaClient>>,
}
inventory::collect!(KafkaPlugin) ;

pub fn new_client(bootstrap_server: &str) -> Option<Box<dyn KafkaClient>> {
    inventory::iter::<KafkaPlugin>.into_iter().find_map(|plugin| {
        (plugin.new_client)(bootstrap_server)
    })
}
